package com.yunyao.framework.audit;

import com.yunyao.common.constant.enums.AuditStatusEnums;
import com.yunyao.common.constant.enums.ReconciliationStatusEnum;
import com.yunyao.common.dto.audit.AuditFlowTypeEnums;
import com.yunyao.common.dto.audit.AuditResultEnums;
import com.yunyao.common.dto.audit.CreateAuditFlowDto;
import com.yunyao.common.exception.AuditException;
import com.yunyao.common.web.enums.ResultMsgEnum;
import com.yunyao.dao.model.BamuReconciliation;
import com.yunyao.dao.service.bamu.IBamuContractNodePayService;
import com.yunyao.dao.service.bamu.IBamuContractWirePayService;
import com.yunyao.dao.service.bamu.IBamuReconciliationOrderMaterialService;
import com.yunyao.dao.service.bamu.IBamuReconciliationService;
import com.yunyao.framework.dto.reconciliation.ReconciliationApprovalDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

@Slf4j
@Component
public class ReconciliationAuditHandle extends AbstractAuditFlowHandle{
    @Autowired
    private IBamuReconciliationOrderMaterialService iBamuReconciliationOrderMaterialService;
    @Autowired
    private IBamuContractWirePayService iBamuContractWirePayService;
    @Autowired
    private IBamuContractNodePayService iBamuContractNodePayService;
    @Autowired
    private IBamuReconciliationService iBamuReconciliationService;

    @Transactional(rollbackFor = AuditException.class)
    public void submit(String bizId) throws AuditException{
        //根据业务ID获取供应商对账信息，不包括已删除的记录
        BamuReconciliation bamuReconciliation = iBamuReconciliationService.getByIdNoDelete(bizId);
        //获取合同名称，用于审批流程创建时的识别
        String contractName = bamuReconciliation.getContractName();
        //获取合同状态，用于审批流程创建时的参数
        Integer status = bamuReconciliation.getStatus();
        //从默认审批模型信息中获取供应商对账模型ID
        String reconciliationId = defaultAuditModelInfo.getReconciliationId();
        try {
            //检查提交的数据是否符合要求
            checkSubmitData(bamuReconciliation);
            //创建审批流程实例，并传入必要的参数
        CreateAuditFlowDto createAuditFlowDto = creatFlow(reconciliationId,
                AuditFlowTypeEnums.MODEL_NAME_RECONCILIATION.getType(),bizId,contractName,String.valueOf(status));
            bamuReconciliation.setProcessInstanceId(createAuditFlowDto.getProcessInstanceId());
            bamuReconciliation.setDeploymentId(createAuditFlowDto.getDeploymentId());
            bamuReconciliation.setModelSchemeInfoId(createAuditFlowDto.getModelSchemeInfoId());
            bamuReconciliation.setProcessVersion(createAuditFlowDto.getProcessVersion());
            //更新供应商对账合同的审批状态为“审批中”
            bamuReconciliation.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT.getType()));
            //更新供应商对账信息
            iBamuReconciliationService.updateById(bamuReconciliation);
        } catch (Exception e) {
            //记录审批流程提交过程中的异常
            log.error("项目对账submit approval error",e);
            //抛出自定义异常，提示审批流程提交失败
            throw new AuditException(e.getMessage());
        }
    }

    /**
     * 审批供应商订单
     * 该方法负责对供应商订单进行审批，根据审批结果供应商订单状态，并触发后续流程
     *
     * @param approvalDto 包含审批信息的数据传输对象
     * @throws AuditException 审批过程中发生异常时抛出
     */
    @Transactional(rollbackFor = AuditException.class)
    public void approval(ReconciliationApprovalDto approvalDto) throws AuditException {
        try {
            //获取业务ID
            String bizId = approvalDto.getId();
            //获取审批结果
            Boolean auditResult = approvalDto.getAuditResult();
            //根据审批结果转换为字符串表示
            String auditResultStr = auditResult ? AuditResultEnums.AGREE.getKey() : AuditResultEnums.REJECT.getKey();
            // 通过业务ID获取供应商对账信息,注意此次未删除记录
            BamuReconciliation bamuReconciliation = iBamuReconciliationService.getByIdNoDelete(bizId);
            //检查审批数据是否符合要求
            checkApprovalData(bamuReconciliation);
            //执行流程，并获取是否结束的标志
            boolean isEnd = executeFlow(bamuReconciliation.getProcessInstanceId(),
                    bamuReconciliation.getDeploymentId(), auditResultStr,
                    approvalDto.getAuditResultMsg(), approvalDto.getAuditFileList());
            //如果流程未结束，则直接返回
            if (!isEnd) {
                return;
            }
            // 根据审批结果更新合同状态
            if (auditResult) {
                // 审批通过的情况下，更新为审批成功状态
                bamuReconciliation.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT_SUCCESS.getType()));
                bamuReconciliation.setStatus(ReconciliationStatusEnum.CONFIRMED_BY_SUPPLIER.getType());
            } else {
                // 审批未通过的情况下，更新为审批拒绝状态
                bamuReconciliation.setAuditStatus(String.valueOf(AuditStatusEnums.AUDIT_REJECT.getType()));
            }
            // 更新供应商对账信息
            iBamuReconciliationService.updateById(bamuReconciliation);

        } catch (Exception e) {
            // 记录审批过程中的异常信息
            log.error("项目对账 approval error", e);
            // 将异常信息包装后抛出
            throw new AuditException(e.getMessage());
        }
    }
    /**
     * 检查审批数据是否符合要求
     * 此方法主要用于校验传入的销售合同对象中的审批数据是否满足继续处理的条件
     * 如果数据不符合要求，将抛出AuditException异常，以阻止不合适的处理流程
     *
     * @param bamuReconciliation 供应商对账对象，包含审批状态、流程实例ID和部署ID等信息
     * @throws AuditException 如果供应商对象为空、审批状态不为“审核中”、流程实例ID为空或部署ID为空时抛出此异常
     */
    private void checkApprovalData(BamuReconciliation bamuReconciliation) throws AuditException {
        // 检查项目对账对象是否为空，如果为空则抛出异常，提示没有数据
        if (Objects.isNull(bamuReconciliation)) {
            throw new AuditException(ResultMsgEnum.NO_DATA);
        }
        // 获取并解析审批状态，检查是否为“审核中”状态，如果不是，则抛出异常，提示提交审批状态错误
        String auditStatus = bamuReconciliation.getAuditStatus();
        if (AuditStatusEnums.AUDIT.getType() != Integer.parseInt(auditStatus)) {
            throw new AuditException(ResultMsgEnum.SUBMIT_AUDIT_STATUS_ERROR);
        }
        // 获取流程实例ID，并检查其是否为空，如果为空则抛出异常
        String processInstanceId = bamuReconciliation.getProcessInstanceId();
        if (StringUtils.isBlank(processInstanceId)) {
            throw new AuditException("processInstanceId is null");
        }
        // 获取部署ID，并检查其是否为空，如果为空则抛出异常
        String deploymentId = bamuReconciliation.getDeploymentId();
        if (StringUtils.isBlank(deploymentId)) {
            throw new AuditException("deploymentId is null");
        }
    }
    public boolean userIsAuditButton(String schemeInfoId, String processInstanceId) {
        try {
            return isCheckAudit(schemeInfoId, processInstanceId);
        } catch (Exception e) {
            log.info("项目对账userIsAuditButton error:{}", e.getMessage());
            return false;
        }
    }
    private void checkSubmitData(BamuReconciliation bamuReconciliation) throws AuditException {

        // 检查传入的对象是否为空，如果为空则抛出异常，提示没有数据可以审核
        if (Objects.isNull(bamuReconciliation)) {
            throw new AuditException(ResultMsgEnum.NO_DATA);
        }

        // 获取并解析审核状态，判断是否处于不合理的审核状态
        String auditStatus = bamuReconciliation.getAuditStatus();
        // 如果审核状态处于审核中、审核成功、审核失败中的任意一种，则抛出异常，提示提交审核状态错误
        if (AuditStatusEnums.AUDIT.getType() == Integer.parseInt(auditStatus)
                && AuditStatusEnums.AUDIT_SUCCESS.getType() == Integer.parseInt(auditStatus)
                && AuditStatusEnums.AUDIT_REJECT.getType() == Integer.parseInt(auditStatus)) {
            throw new AuditException(ResultMsgEnum.SUBMIT_AUDIT_STATUS_ERROR);
        }

//        // 获取并解析绑定合同状态，判断是否已经绑定合同
//        Integer status = bamuReconciliation.getStatus();
//        // 如果绑定合同状态为已绑定，则抛出异常，提示绑定合同状态错误
//        if (BindContractStatusEnums.YES.getType() == status) {
//            throw new AuditException(ResultMsgEnum.BIND_CONTRACT_STATUS_ERROR);
//        }
    }
}
